#pragma once
#include "Log.hpp"
#include <cerrno>
#include <cstdlib>
#include<iostream>
#include <strings.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<cstring>

class Sock
{
public:
    Sock(){}
    int Socket()
    {
        int _serversock=socket(AF_INET, SOCK_DGRAM, 0);
        if(_serversock < 0)
        {
            logMessage(FATAL, "%d:%s", errno,strerror(errno));
            exit(-1);
        }
        return _serversock;
    }
    void Bind(int sock,uint16_t port,std::string ip)
    {
        struct sockaddr_in server;
        bzero(&server, sizeof(server));
        server.sin_family=AF_INET;
        server.sin_port=htons(port);
        server.sin_addr.s_addr=inet_addr(ip.c_str());
        if(bind(sock, (struct sockaddr*)&server, sizeof(server)) < 0)
        {
            logMessage(FATAL, "%d:%s", errno,strerror(errno));
            exit(-2);
        }
    }
    void Listen(int sock)
    {
        if(listen(sock, gbacklog) < 0)
        {
            logMessage(FATAL, "%d:%s", errno,strerror(errno));
            exit(-3);
        }
        logMessage(NORMAL, "listen() done sock: %d", sock);
    }
    int Accpet(int sock,uint16_t* port,std::string* ip)
    {
        //这里应该接受来自于客户端的消息，这里的server应该是客户端的服务器
        struct sockaddr_in server;
        bzero(&server,sizeof(server));
        socklen_t len=sizeof(server);
        int _serversock=accept(sock, (struct sockaddr*)&server, &len);
        if(_serversock < 0)
        {
            logMessage(FATAL, "%d:%s", errno,strerror(errno));
            exit(-1);
        }
        if(port){
            *port=ntohs(server.sin_port);
        }
        if(ip){
            *ip=inet_ntoa(server.sin_addr);
        }
    }
    bool Connet(int sock,uint16_t& server_port,std::string server_ip)
    {
        struct sockaddr_in server;
        bzero(&server,sizeof(server));
        socklen_t len=sizeof(server);
        server.sin_family=AF_INET;
        server.sin_port=htons(server_port);
        server.sin_addr.s_addr=inet_addr(server_ip.c_str());
        if(connect(sock, (struct sockaddr*)&server, len) == 0)
        {
            logMessage(NORMAL, "Connet done sock:%d", sock);
            return true;
        }
        else{
            return false;
        }
    }
private:
    static const int gbacklog=20;
};